package com.example.demo.sensitive.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import com.example.demo.sensitive.dto.response.CheckResultResponse;
import com.example.demo.sensitive.entity.CheckResult;
import com.example.demo.sensitive.mapper.CheckResultMapper;
import com.example.demo.sensitive.service.CheckResultService;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName CheckResultServiceImpl
 * @Description 检查结果服务实现类
 * @Author System
 * @Date 2025/9/19
 **/
@Service
public class CheckResultServiceImpl extends ServiceImpl<CheckResultMapper, CheckResult> implements CheckResultService {

    @Override
    public Page<CheckResultResponse> getPageList(Long taskId, int current, int size, String category,
                                                Integer level, String processStatus, String keyword) {
        Page<CheckResult> page = new Page<>(current, size);
        Page<CheckResult> result = baseMapper.selectPage(page, null);
        
        Page<CheckResultResponse> responsePage = new Page<>(current, size);
        responsePage.setTotal(result.getTotal());
        responsePage.setSize(result.getSize());
        responsePage.setCurrent(result.getCurrent());
        
        return responsePage;
    }

    @Override
    public CheckResultResponse getById(Long id) {
        CheckResult entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("结果不存在");
        }
        
        return convertToResponse(entity);
    }

    @Override
    public List<CheckResultResponse> getByTaskId(Long taskId) {
        // 查询该任务的所有结果
        List<CheckResult> results = baseMapper.selectByTaskId(taskId);
        
        // 转换为响应对象
        List<CheckResultResponse> responses = new ArrayList<>();
        if (results != null) {
            for (CheckResult result : results) {
                responses.add(convertToResponse(result));
            }
        }
        
        return responses;
    }

    @Override
    public List<CheckResultResponse> getHighRiskResults(Long taskId) {
        List<CheckResult> allResults = baseMapper.selectByTaskId(taskId);
        List<CheckResult> highRiskResults = new ArrayList<>();
        
        for (CheckResult result : allResults) {
            String context = result.getContext();
            // 判断是否为高风险：政治敏感、违法违规等
            if (context != null && (
                context.contains("政治敏感") || 
                context.contains("违法违规") ||
                context.contains("等级: 4") ||
                context.contains("等级: 3")
            )) {
                highRiskResults.add(result);
            }
        }
        
        // 转换为响应对象
        List<CheckResultResponse> responses = new ArrayList<>();
        for (CheckResult result : highRiskResults) {
            responses.add(convertToResponse(result));
        }
        
        return responses;
    }

    @Override
    public void ignoreResult(Long id, String note) {
        CheckResult entity = baseMapper.selectById(id);
        if (entity != null) {
            entity.setProcessStatus("IGNORED");
            entity.setSuggestion(note != null ? note : "用户已忽略");
            baseMapper.updateById(entity);
        }
    }

    @Override
    public void batchIgnore(List<Long> ids, String note) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        for (Long id : ids) {
            CheckResult entity = baseMapper.selectById(id);
            if (entity != null) {
                entity.setProcessStatus("IGNORED");
                entity.setSuggestion(note != null ? note : "批量忽略");
                baseMapper.updateById(entity);
            }
        }
    }

    @Override
    public void confirmResult(Long id, String note) {
        CheckResult entity = baseMapper.selectById(id);
        if (entity != null) {
            entity.setProcessStatus("CONFIRMED");
            entity.setSuggestion(note != null ? note : "已确认为敏感内容，需要处理");
            baseMapper.updateById(entity);
        }
    }

    @Override
    public String generateCleanSQL(Long id, String action) {
        CheckResult result = baseMapper.selectById(id);
        if (result == null) {
            throw new RuntimeException("检查结果不存在");
        }
        
        String tableName = result.getTableName();
        String columnName = result.getColumnName();
        String recordId = result.getRecordId();
        String sensitiveWord = result.getSensitiveWord();
        
        switch (action.toLowerCase()) {
            case "replace":
                // 替换敏感词为星号
                return String.format(
                    "UPDATE %s SET %s = REPLACE(%s, '%s', '%s') WHERE id = %s;",
                    tableName, columnName, columnName, 
                    escapeSql(sensitiveWord), 
                    "*".repeat(sensitiveWord.length()), 
                    recordId
                );
                
            case "delete":
                // 删除整条记录
                return String.format(
                    "DELETE FROM %s WHERE id = %s;",
                    tableName, recordId
                );
                
            case "clear":
                // 清空字段内容
                return String.format(
                    "UPDATE %s SET %s = '' WHERE id = %s;",
                    tableName, columnName, recordId
                );
                
            case "mask":
                // 掩码处理，保留前后字符
                String masked = maskSensitiveWord(sensitiveWord);
                return String.format(
                    "UPDATE %s SET %s = REPLACE(%s, '%s', '%s') WHERE id = %s;",
                    tableName, columnName, columnName,
                    escapeSql(sensitiveWord), masked, recordId
                );
                
            default:
                throw new IllegalArgumentException("不支持的清理动作: " + action);
        }
    }

    @Override
    public List<String> batchGenerateCleanSQL(List<Long> ids, String action) {
        List<String> sqls = new ArrayList<>();
        
        if (ids == null || ids.isEmpty()) {
            return sqls;
        }
        
        sqls.add("-- 批量清理SQL语句");
        sqls.add("-- 生成时间: " + LocalDateTime.now());
        sqls.add("-- 清理动作: " + action);
        sqls.add("");
        
        for (Long id : ids) {
            try {
                String sql = generateCleanSQL(id, action);
                sqls.add(sql);
            } catch (Exception e) {
                sqls.add("-- 错误: ID " + id + " 生成失败: " + e.getMessage());
            }
        }
        
        return sqls;
    }

    @Override
    public Integer executeCleanSQL(String sql, Object options) {
        // 安全检查：只允许特定的SQL操作
        if (sql == null || sql.trim().isEmpty()) {
            throw new IllegalArgumentException("SQL语句不能为空");
        }
        
        String trimmedSql = sql.trim().toLowerCase();
        
        // 只允许UPDATE和DELETE操作，禁止DROP、CREATE等危险操作
        if (!trimmedSql.startsWith("update") && !trimmedSql.startsWith("delete")) {
            throw new SecurityException("只允许执行UPDATE和DELETE操作");
        }
        
        // 检查是否包含WHERE条件（防止全表操作）
        if (!trimmedSql.contains("where")) {
            throw new SecurityException("必须包含WHERE条件，禁止全表操作");
        }
        
        // 实际项目中这里应该连接到目标数据库执行SQL
        // 为了安全起见，这里只返回模拟结果
        
        // 模拟执行结果：影响行数
        return 1; // 假设影响1行
    }

    @Override
    public ResultStatistics getResultStatistics(Long taskId) {
        List<CheckResult> allResults = baseMapper.selectByTaskId(taskId);
        
        ResultStatistics stats = new ResultStatistics();
        stats.setTotalResults(allResults.size());
        
        int highRiskResults = 0;
        int pendingResults = 0;
        int processedResults = 0;
        
        for (CheckResult result : allResults) {
            // 统计处理状态
            String status = result.getProcessStatus();
            if ("PENDING".equals(status)) {
                pendingResults++;
            } else if ("IGNORED".equals(status) || "CONFIRMED".equals(status) || "PROCESSED".equals(status)) {
                processedResults++;
            }
            
            // 统计高风险结果（可以根据敏感词类别判断）
            String context = result.getContext();
            if (context != null && (context.contains("政治敏感") || context.contains("违法违规"))) {
                highRiskResults++;
            }
        }
        
        stats.setHighRiskResults(highRiskResults);
        stats.setPendingResults(pendingResults);
        stats.setProcessedResults(processedResults);
        
        return stats;
    }

    @Override
    public List<TableColumnStatistics> getTableColumnStatistics(Long taskId) {
        List<CheckResult> allResults = baseMapper.selectByTaskId(taskId);
        Map<String, TableColumnStatistics> statsMap = new HashMap<>();
        
        for (CheckResult result : allResults) {
            String key = result.getTableName() + "." + result.getColumnName();
            
            TableColumnStatistics stats = statsMap.computeIfAbsent(key, k -> {
                TableColumnStatistics newStats = new TableColumnStatistics();
                newStats.setTableName(result.getTableName());
                newStats.setColumnName(result.getColumnName());
                newStats.setResultCount(0);
                return newStats;
            });
            
            stats.setResultCount(stats.getResultCount() + 1);
        }
        
        // 按结果数量降序排序
        return statsMap.values().stream()
                .sorted((a, b) -> b.getResultCount().compareTo(a.getResultCount()))
                .collect(Collectors.toList());
    }

    @Override
    public byte[] exportResults(Long taskId, String format) {
        List<CheckResult> results = baseMapper.selectByTaskId(taskId);
        
        if ("excel".equalsIgnoreCase(format)) {
            return exportToExcel(results, taskId);
        } else if ("csv".equalsIgnoreCase(format)) {
            return exportToCsv(results, taskId);
        } else {
            throw new IllegalArgumentException("不支持的导出格式: " + format);
        }
    }

    @Override
    public void cleanTaskResults(Long taskId) {
        // 删除指定任务的所有检查结果
        List<CheckResult> results = baseMapper.selectByTaskId(taskId);
        for (CheckResult result : results) {
            baseMapper.deleteById(result.getId());
        }
    }

    @Override
    public Integer cleanExpiredResults(int days) {
        // 删除指定天数之前的检查结果
        LocalDateTime cutoffTime = LocalDateTime.now().minusDays(days);
        
        // 查询过期结果
        List<CheckResult> expiredResults = new ArrayList<>();
        List<CheckResult> allResults = baseMapper.selectList(null);
        
        for (CheckResult result : allResults) {
            if (result.getFindTime() != null && result.getFindTime().isBefore(cutoffTime)) {
                expiredResults.add(result);
            }
        }
        
        // 删除过期结果
        for (CheckResult result : expiredResults) {
            baseMapper.deleteById(result.getId());
        }
        
        return expiredResults.size();
    }
    
    /**
     * 生成查询SQL
     */
    private String generateQuerySQL(CheckResult result) {
        return String.format(
            "SELECT * FROM %s.%s WHERE id = %s",
            result.getDatabaseName(),
            result.getTableName(),
            result.getRecordId()
        );
    }
    
    /**
     * 从上下文中提取分类信息
     */
    private String extractCategoryFromContext(String context) {
        if (context == null) return "";
        
        // 解析类似 "在敏感词库中发现: 色情 (类别: 不文明词汇, 等级: 4)" 的格式
        if (context.contains("类别:")) {
            String[] parts = context.split("类别:");
            if (parts.length > 1) {
                String categoryPart = parts[1];
                if (categoryPart.contains(",")) {
                    return categoryPart.split(",")[0].trim();
                } else if (categoryPart.contains(")")) {
                    return categoryPart.split("\\)")[0].trim();
                }
            }
        }
        return "";
    }
    
    /**
     * 生成完整内容信息
     */
    private String generateFullContent(CheckResult result) {
        return String.format("""
                表名: %s
                字段名: %s
                记录ID: %s
                敏感词: %s
                检查时间: %s
                检查结果: %s
                处理建议: %s""",
                result.getTableName(),
                result.getColumnName(),
                result.getRecordId(),
                result.getSensitiveWord(),
                result.getFindTime(),
                result.getContext(),
                result.getSuggestion() != null ? result.getSuggestion() : "暂无建议");
    }
    
    /**
     * 转换实体为响应对象
     */
    private CheckResultResponse convertToResponse(CheckResult result) {
        CheckResultResponse response = new CheckResultResponse();
        
        // 使用Spring BeanUtils自动复制属性
        BeanUtils.copyProperties(result, response);
        
        // 处理特殊字段映射
        response.setKeyword(result.getSensitiveWord()); // 前端期望的字段名
        response.setCreateTime(result.getFindTime()); // 映射创建时间
        response.setContextContent(generateFullContent(result)); // 完整内容
        response.setQuerySql(generateQuerySQL(result)); // 查询SQL
        response.setCategory(extractCategoryFromContext(result.getContext())); // 分类
        
        return response;
    }
    
    /**
     * SQL转义，防止SQL注入
     */
    private String escapeSql(String input) {
        if (input == null) {
            return "";
        }
        return input.replace("'", "''")
                   .replace("\\", "\\\\")
                   .replace("\n", "\\n")
                   .replace("\r", "\\r")
                   .replace("\t", "\\t");
    }
    
    /**
     * 掩码处理敏感词
     */
    private String maskSensitiveWord(String word) {
        if (word == null || word.length() <= 2) {
            return "*".repeat(word != null ? word.length() : 1);
        }
        
        if (word.length() <= 4) {
            // 短词：保留首尾各1个字符
            return word.charAt(0) + "*".repeat(word.length() - 2) + word.charAt(word.length() - 1);
        } else {
            // 长词：保留首尾各2个字符
            return word.substring(0, 2) + 
                   "*".repeat(word.length() - 4) + 
                   word.substring(word.length() - 2);
        }
    }
    
    /**
     * 导出为Excel格式
     */
    private byte[] exportToExcel(List<CheckResult> results, Long taskId) {
        // 简化实现：返回CSV格式（实际项目中可使用POI生成Excel）
        return exportToCsv(results, taskId);
    }
    
    /**
     * 导出为CSV格式
     */
    private byte[] exportToCsv(List<CheckResult> results, Long taskId) {
        StringBuilder csv = new StringBuilder();
        
        // CSV头部
        csv.append("任务ID,表名,字段名,记录ID,敏感词,分类,上下文,处理状态,发现时间,处理建议\n");
        
        // CSV数据
        for (CheckResult result : results) {
            csv.append(String.format("\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n",
                    taskId,
                    escapeCsv(result.getTableName()),
                    escapeCsv(result.getColumnName()),
                    escapeCsv(result.getRecordId()),
                    escapeCsv(result.getSensitiveWord()),
                    escapeCsv(extractCategoryFromContext(result.getContext())),
                    escapeCsv(result.getContext()),
                    escapeCsv(result.getProcessStatus()),
                    result.getFindTime() != null ? result.getFindTime().toString() : "",
                    escapeCsv(result.getSuggestion())
            ));
        }
        
        return csv.toString().getBytes(StandardCharsets.UTF_8);
    }
    
    /**
     * CSV转义处理
     */
    private String escapeCsv(String input) {
        if (input == null) {
            return "";
        }
        return input.replace("\"", "\"\"")
                   .replace("\n", " ")
                   .replace("\r", " ");
    }
}
